package com.ys.service.finance.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.config.MenuId;
import com.ys.dto.AddDto;
import com.ys.entity.business.TbBaseInfo;
import com.ys.entity.finance.*;
import com.ys.entity.flow.YspModel;
import com.ys.entity.sys.*;
import com.ys.enume.finance.TcwFinancialTransactionFlowEnum;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.finance.TcwCompanyAccountTransferItemMapper;
import com.ys.mapper.finance.TcwCompanyAccountTransferMapper;
import com.ys.mapper.hr.HrMapper;
import com.ys.service.business.TcwAccountDetailedForCompanyService;
import com.ys.service.finance.TcwCompanyAccountTransferService;
import com.ys.service.finance.TcwFinancialTransactionFlowService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.CheckUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.*;

/**
 *
 */
@Service("tcwCompanyAccountTransferService")
public class TcwCompanyAccountTransferServiceImpl implements TcwCompanyAccountTransferService {
	@Autowired
	private TcwCompanyAccountTransferMapper tcwCompanyAccountTransferMapper;

	@Autowired
	private TcwCompanyAccountTransferItemMapper tcwCompanyAccountTransferItemMapper;

	@Autowired
	private YspTaskService yspTaskService;

	@Autowired
	private CheckUtil checkUtil;

	@Autowired
	private HrMapper hrMapper;

	@Autowired
	private TcwAccountDetailedForCompanyService tcwAccountDetailedForCompanyService;

	@Autowired
	private TcwFinancialTransactionFlowService tcwFinancialTransactionFlowService;
	/*
	 * 新增
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R add(Map<String, Object> params) throws Exception {
		//验证
		String msg = yzMsg(params);
		if (msg != null){
			return R.error(msg);
		}
		TcwCompanyAccountTransfer tcwCompanyAccountTransfer = JSON.parseObject(JSON.toJSONString(params), TcwCompanyAccountTransfer.class);
		List<Map<String, Object>> paramsNewByItem = new ArrayList<>();
		if(params.get("subData")!=null){
			JSONArray subData = JSON.parseArray(params.get("subData").toString());
			for (int i = 0; i < subData.size(); i++) {
				JSONObject jSONObject = subData.getJSONObject(i);
				Map<String, Object> paramsNew = new HashMap<>();
				for (String key : jSONObject.keySet()) {
					paramsNew.put(key,jSONObject.get(key));
				}

//				paramsNew.put("pid",tcwCompanyAccountTransfer.getId());//单号
				paramsNewByItem.add(paramsNew);
			}

		}else {
			return R.error("详情信息为空！");
		}
		String wrongmassage=null;
		for (int i = 0; i < paramsNewByItem.size(); i++){
			Map<String, Object> item=paramsNewByItem.get(i);
			String out=item.get("vidOut").toString();
			String in=item.get("vidIn").toString();
			if(out.equals(in)){
				wrongmassage="划出与划入公司不能相同！";
			}
		}
		if(wrongmassage !=null){
			return R.error(wrongmassage);
		}
		String loginUserId = ShiroUtils.getUserId();
		//获取制单人信息
		TsUserChange tsUserChange = new TsUserChange().setUserId(ShiroUtils.getUserId()).setOrderby("A.CreateTime DESC").queryFirst();
		if(tsUserChange!=null){
			tcwCompanyAccountTransfer.setCreateChangeId(tsUserChange.getId());//制单人变更信息
		}else {
			return R.error("未查询到制单人信息！");
		}

		tcwCompanyAccountTransfer.setStatus(1);
		tcwCompanyAccountTransfer.setEffectStock(FlowEnum.EffectStock.NOT_EFFECT.value);

		tcwCompanyAccountTransferMapper.insert(tcwCompanyAccountTransfer);
		for(Map<String, Object> item:paramsNewByItem){
			if(item.get("premark")!=null){
				item.put("remark",item.get("premark"));
			}
			TcwCompanyAccountTransferItem tcwCompanyAccountTransferItem = JSON.parseObject(JSON.toJSONString(item), TcwCompanyAccountTransferItem.class);
			tcwCompanyAccountTransferItem.setStatus(1);
			tcwCompanyAccountTransferItem.setPbid(tcwCompanyAccountTransfer.getBid());

			if (!item.get("amount").toString().matches("\\d+(\\.\\d{0,2})?")){
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return R.error("交易金额最多两位小数！");
			}
			tcwCompanyAccountTransferItemMapper.insert(tcwCompanyAccountTransferItem);
		}
		YsMenu ysMenu = new YsMenu().setId(MenuId.TCW_CompanyAccountTransfer).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, tcwCompanyAccountTransfer.getBid(), createUserId);
		}
		return R.ok(AddDto.gotoEdit("/web/finance/tcwCompanyAccountTransfer/toEdit?bid=" + tcwCompanyAccountTransfer.getBid()));
	}


	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R edit(String bid,Map<String, Object> params) throws Exception {
		Integer stateFlow = yspTaskService.flowState(bid);
		if (stateFlow != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("非制单中数据，无法修改");
		}
		// 验证是否制单人
		YsProcInst entity = new YsProcInst().setBid(bid).queryFirst();
		if (!entity.getCreateUserId().equals(ShiroUtils.getUserId())) {
			return R.error("非制单人无法修改");
		}

		TcwCompanyAccountTransfer tcwCompanyAccountTransfer = JSON.parseObject(JSON.toJSONString(params), TcwCompanyAccountTransfer.class);

		tcwCompanyAccountTransferMapper.update(tcwCompanyAccountTransfer);
		//验证详情信息
		List<Map<String, Object>> paramsNewByItem = new ArrayList<>();
		if(params.get("subData")!=null){
			JSONArray subData = JSON.parseArray(params.get("subData").toString());
			for (int i = 0; i < subData.size(); i++) {
				JSONObject jSONObject = subData.getJSONObject(i);
				Map<String, Object> paramsNew = new HashMap<>();
				for (String key : jSONObject.keySet()) {
					paramsNew.put(key,jSONObject.get(key));
				}
				paramsNew.put("pbid",tcwCompanyAccountTransfer.getBid());//单号
				paramsNewByItem.add(paramsNew);
			}
		}else {
			return R.error("详情信息为空！");
		}

		for(Map<String, Object> item:paramsNewByItem){
			if(item.get("premark")!=null){
				item.put("remark",item.get("premark"));
			}
			TcwCompanyAccountTransferItem tcwCompanyAccountTransferItem = JSON.parseObject(JSON.toJSONString(item), TcwCompanyAccountTransferItem.class);
			if(tcwCompanyAccountTransferItem.getId()!=null && !"".equals(tcwCompanyAccountTransferItem.getId())){
				//修改
				tcwCompanyAccountTransferItemMapper.update(tcwCompanyAccountTransferItem);
			}else {//新增
				tcwCompanyAccountTransferItem.setStatus(1);
				hrMapper.deleteTcwCompanyAccountTransferItemByBid(bid);
				if (!item.get("amount").toString().matches("\\d+(\\.\\d{0,2})?")){
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return R.error("交易金额最多两位小数！");
				}
				tcwCompanyAccountTransferItemMapper.insert(tcwCompanyAccountTransferItem);
			}
		}
		return R.ok(AddDto.gotoEdit("/web/finance/tcwCompanyAccountTransfer/toEdit?bid=" + tcwCompanyAccountTransfer.getBid()));


	}

	@Override
	@Transactional
	public R deleteTrue(Long id) throws Exception {
		if (id == null) {
			return R.error("ID不能为空");
		}
		TcwCompanyAccountTransfer entity = new TcwCompanyAccountTransfer().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();

		if (!tsUserChange.getUserId().equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}

		// 删除主数据
		tcwCompanyAccountTransferMapper.deleteTrue(id);

		// 删除子数据
		List<TcwCompanyAccountTransferItem> listDetail = new TcwCompanyAccountTransferItem().setPbid(entity.getBid()).queryList();
		for(TcwCompanyAccountTransferItem detail : listDetail) {
			tcwCompanyAccountTransferItemMapper.deleteTrue(detail.getId());
		}

		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	private String yzMsg(Map<String, Object> infoMap){
		//验证导入字段
		String backMsg = "";
		//获取pc字段数据
		List<YsCol> listField = new YsCol()
				.where("A.MenuId = "+10361L)
				.setOrderby("A.SortNo ASC")
				.queryList();
		//验证必填字段的非空；其他字段的长度限制、类型
		try {
			backMsg = checkUtil.checkTableColLengthAndDataType(
					"TCW_CompanyAccountTransfer",
					listField,
					infoMap,
					ysColItem->ysColItem.getFormEditRequired()!=null && ysColItem.getFormEditRequired() == 1
			);
			if(backMsg!=null && !"".equals(backMsg)){//若有误，则跳过这条信息
				return backMsg;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


	@Override
	@Transactional
	public R toDelByItem(Long id) throws Exception {

		TcwCompanyAccountTransferItem tcwCompanyAccountTransferItem = new TcwCompanyAccountTransferItem();
		tcwCompanyAccountTransferItem.setId(id);
		tcwCompanyAccountTransferItem.setStatus(0);
		tcwCompanyAccountTransferItemMapper.update(tcwCompanyAccountTransferItem);
		return R.ok();
	}
	/**
	 * 流转通过
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R flowPass(String bid, String loginUserId) throws Exception {

		TcwCompanyAccountTransfer entity = new TcwCompanyAccountTransfer().setBid(bid).queryFirst();


		YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();

		// 若流程是初始化状态，需要验证账户金额
		if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
			String errorMsg = "";
			//获取详情信息
			List<TcwCompanyAccountTransferItem> sonList = new TcwCompanyAccountTransferItem().setPbid(bid).queryList();
			for(TcwCompanyAccountTransferItem sonItem:sonList){
				TbCompanyBankInfo bankInfoByOut = new TbCompanyBankInfo()
						.setVid(sonItem.getVidOut())
						.queryFirst();
//				boolean isCapital = tcwFinancialTransactionFlowService.isCapital(bankInfoByOut.getId(),sonItem.getAmount().negate());
//				if(!isCapital){
//					errorMsg += sonItem.getVidOut()+"账户金额不足；";
//				}
			}
			if(checkUtil.isNotNullByObject(errorMsg)){
				return R.error(errorMsg);
			}
		}

		Flow f = yspTaskService.flowPass(entity.getBid(), loginUserId);
		if (f.getCode() == Flow.Code.FAILED.value) {
			return R.error(f.getMsg());
		} else {
			if (f.getState() == Flow.State.FINISH.value) {
				flowFinish(entity.getBid());
			}
			return R.ok();
		}
	}

	/**
	 * 流转结束
	 */
	@Override
	@Transactional
	public void flowFinish(String bid) throws Exception {

		TcwCompanyAccountTransfer entity = new TcwCompanyAccountTransfer().setBid(bid).queryFirst();
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		Date theDate = new Date();
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		entity.setUpdateTime(theDate);

		//获取详情信息
		List<TcwCompanyAccountTransferItem> sonList = new TcwCompanyAccountTransferItem().setPbid(bid).queryList();
		for (TcwCompanyAccountTransferItem sonItem : sonList){
			TcwFinancialTransactionType financialTransactionType = new TcwFinancialTransactionType()
					.setIntegrityType(sonItem.getBaseInfoType())
					.setStatus(1)
					.queryFirst();

			TbCompanyBankInfo bankInfoByIn = new TbCompanyBankInfo()
					.setVid(sonItem.getVidIn())
					.queryFirst();
			TbCompanyBankInfo bankInfoByOut = new TbCompanyBankInfo()
					.setVid(sonItem.getVidOut())
					.queryFirst();
			if(financialTransactionType!=null && financialTransactionType.getId()!=null
				&& bankInfoByIn!=null && bankInfoByIn.getId()!=null
					&& bankInfoByOut!=null && bankInfoByOut.getId()!=null){
				TbBaseInfo tbBaseInfo = new TbBaseInfo().setFinanceBid(financialTransactionType.getBid()).queryFirst();
				if(tbBaseInfo!=null && tbBaseInfo.getId()!=null){
					R res = tcwFinancialTransactionFlowService.add(true, bankInfoByOut.getId(), tbBaseInfo.getBid(),
							bankInfoByIn.getVyhzhmc(), bankInfoByIn.getVkhh(), bankInfoByIn.getVyhzh(), sonItem.getAmount().negate(),
							sonItem.getCreateTime(),theDate,entity.getWriteTime(),"公司账户资金转账："+entity.getBid()+"，"+(sonItem.getRemark()!=null?sonItem.getRemark():""),
							TcwFinancialTransactionFlowEnum.FromType.TCW_CompanyAccountTransferItem.value,sonItem.getId());
					if(res.getCode().equals( R.Code.FAILED.value)){
						throw new IllegalArgumentException(res.getMsg());
					}
					R res2 = tcwFinancialTransactionFlowService.add(true, bankInfoByIn.getId(), tbBaseInfo.getBid(),
							bankInfoByOut.getVyhzhmc(), bankInfoByOut.getVkhh(), bankInfoByOut.getVyhzh(), sonItem.getAmount(),
							sonItem.getCreateTime(),theDate,entity.getWriteTime(),"公司账户资金转账："+entity.getBid()+"，"+(sonItem.getRemark()!=null?sonItem.getRemark():""),
							TcwFinancialTransactionFlowEnum.FromType.TCW_CompanyAccountTransferItem.value,sonItem.getId());
					if(res2.getCode().equals(R.Code.FAILED.value)){//失败
						throw new IllegalArgumentException(res2.getMsg());
						//return R.error(res2.getMsg());
					}

				}

			}


			/*
			//获取流水表信息
			TcwAccountDetailedForCompany tcwAccountDetailedForCompany = new TcwAccountDetailedForCompany()
					.setId(sonItem.getAccountDetailedForCompanyId()).queryFirst();
			if(tcwAccountDetailedForCompany!=null){
				BigDecimal returnAmount = sonItem.getAmount();
				tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
						tcwAccountDetailedForCompany.getVgsbm(),tcwAccountDetailedForCompany.getVgsjc(),
						tcwAccountDetailedForCompany.getVgsbmp(),tcwAccountDetailedForCompany.getVgsjcp(),
						tcwAccountDetailedForCompany.getVjylx(), returnAmount.negate(),theDate, theDate,"公司账户资金转账："+entity.getBid()+"，备注"+(tcwAccountDetailedForCompany.getVbz()!=null ? tcwAccountDetailedForCompany.getVbz():""),
						tcwAccountDetailedForCompany.getWriteTime());

				tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJcNoTrigger(
						tcwAccountDetailedForCompany.getVgsbmp(),tcwAccountDetailedForCompany.getVgsjcp(),
						tcwAccountDetailedForCompany.getVgsbm(),tcwAccountDetailedForCompany.getVgsjc(),
						tcwAccountDetailedForCompany.getVjylx(), returnAmount,theDate, theDate,"公司账户资金转账："+entity.getBid()+"，备注"+(tcwAccountDetailedForCompany.getVbz()!=null ? tcwAccountDetailedForCompany.getVbz():""),
						tcwAccountDetailedForCompany.getWriteTime());
			}

			 */
			
		}

		//修改信息
		tcwCompanyAccountTransferMapper.update(entity);

	}

	@Override
	public List<Map<String, Object>> getItemList( String bid){
		List<Map<String, Object>> itemList = new TcwCompanyAccountTransferItem()
				.addLeftJoin("TB_CompanyBankInfo B ON B.Vid=A.VidOut ")
				.addLeftJoin("TB_CompanyBankInfo C ON C.Vid=A.VidIn ")
				.addField("A.remark premark,B.vid vidOut,B.vyhzhmc vyhzhmcOut,B.vkhh vkhhOut,B.vyhzh vyhzhOut," +
						"C.vid vidIn,C.vyhzhmc vyhzhmcIn,C.vkhh vkhhIn,C.vyhzh vyhzhIn")
				.setPbid(bid)
				.queryMap();
		return itemList;
	}

	@Override
	public Map<String,Object> getExtraParam( String bid){
		Map<String,Object> extraParam = new TcwCompanyAccountTransfer()
				.addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
				.addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd HH:mm:ss') AS auditingTime")//审核时间
				.addLeftJoin("TB_CompanyInfo G ON G.vid=A.CompanyVid")
				.addField("G.Vname vName")
				.addLeftJoin("(SELECT ISNULL(SUM(S.Amount),0) AS amount,S.Pbid FROM TCW_CompanyAccountTransferItem S GROUP BY S.Pbid) B ON B.Pbid = A.Bid")
				.addField("B.amount AS totalAmount")//付款总金额
				.setBid(bid)
				.queryFirstMap();
		return extraParam;
	}

}
